"""
shallow copy：建立一个新的对象，但对象内部的元素依然是原对象中元素的引用。单个的整数是不可变对象。不可变对象会直接赋值，可变对象会拷贝元素的引用
deep copy：copy全部层，建立新的数据空间，相当于Ctrl+C。新变量与旧变量互相直接不影响
"""
import copy
def shallow_copy():
    a=[1,2,[3,4]]
    b =copy.copy(a)
    b[2].append(5)      #b[2]和a[2]是同一元素引用，所以改变b[2]会影响a[2]。
    b[1]=6    #整数时不可变对象，修改b[1]不会影响a[1]
    print(f'新变量的地址是{id(b)}\n旧变量的地址是{id(a)}')
    print(f'b[2]的地址是{id(b[2])}\na[2]的地址是{id(a[2])}')
    print(f'b[0]的地址是{id(b[0])}\na[0]的地址是{id(a[0])}')       #地址都是一样的
    print(a)     #浅拷贝后，新旧变量的可变对象会相互影响
    print(b)

def deep_copy():
    a = ['name',1,[2,3]]
    b = copy.deepcopy(a)
    b [2].append(7)

    print(f'原列表{a}，新列表{b}')
    print(f'b[2]的地址是{id(b[2])}\na[2]的地址是{id(a[2])}')
    print(f'b[0]的地址是{id(b[0])}\na[0]的地址是{id(a[0])}')    #b[0]和a[0]对应的是字符串，不可变类型，所以地址相同

class Hero():
    def __init__(self,energy,blood):
        self.energy=energy
        self.blood=blood

def DeepCopy2():
    old_hero = Hero(100,100)
    new_hero = copy.deepcopy(old_hero)
    new_hero.energy=50
    new_hero.blood=10
    print(old_hero.energy)     #新对象改变不会对就对象产生影响
    print(old_hero.blood)

if __name__ == '__main__':
    # shallow_copy()
    # deep_copy()
    DeepCopy2()